﻿using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using log4net;
using Pixster.Models;

namespace Pixster.Controllers.Helpers
{
    public static class ManifestHelper
    {
        private static readonly ILog LOG = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private const string SITEMAP_FILE = "sitemap.xml";
        private static string _rootDirectory;

        public static List<PixDirectory> Sitemap { get; private set; }

        public static List<PixDirectory> GetSitemap(string serverPath)
        {
            if (Sitemap != null)
            {
                LOG.Debug("Sitemap exists, returning.");
                return Sitemap;
            }

            var filePath = Path.Combine(serverPath, SITEMAP_FILE);

            var sitemap = FileHelper<List<PixDirectory>>.LoadFromDisk(filePath);

            if (sitemap == null)
            {
                LOG.Info("Creating new sitemap.");
                sitemap = BuildSitemap(serverPath);
                FileHelper<List<PixDirectory>>.SaveToDisk(sitemap, filePath);
            }

            return Sitemap = sitemap;
        }

        private static List<PixDirectory> BuildSitemap(string rootPath)
        {
            var list = Directory.GetDirectories(rootPath);
            if (list == null) return null;

            _rootDirectory = rootPath;

            var result = new List<PixDirectory>(list.Length);

            foreach (var dir in list)
            {
                var dirName = GetNameFromPath(dir);
                var directory = new PixDirectory
                {
                    Name = dirName,
                    SeoName = AppHelper.SeoName(dirName),
                    DirectoryPath = dir,
                    Albums = GetAlbumns(dir)
                };

                if (directory.Albums != null && directory.Albums.Count > 0)
                {
                    result.Add(directory);
                }
            }

            return result;
        }

        private static List<PixAlbum> GetAlbumns(string path)
        {
            var list = Directory.GetDirectories(path);
            if (list == null) return null;

            var result = new List<PixAlbum>(list.Length);

            foreach (var dir in list)
            {
                if (dir.StartsWith(AppHelper.SvnDirectory)) continue;
                if (dir.StartsWith(AppHelper.CacheDirctory)) continue;

                var name = GetNameFromPath(dir);

                var album = new PixAlbum
                {
                    Name = name,
                    DirectoryPath = Path.Combine(path, dir),
                    SeoName = AppHelper.SeoName(name),
                    Photos = GetPhotos(dir)
                };

                if (album.Photos != null && album.Photos.Count > 0)
                {
                    result.Add(album);
                }
            }
            return result;
        }

        private static List<PixPhoto> GetPhotos(string directoryPath)
        {
            var fileList = Directory.GetFiles(directoryPath);

            if (fileList == null || fileList.Length <= 0) return null;

            CheckCacheDirectory(directoryPath);

            var photos = new List<PixPhoto>();

            foreach (var f in fileList)
            {
                var fileName = GetNameFromPath(f);

                var match = Regex.Match(fileName, "^.*\\.(jpg|JPG|gif|GIF|png|PNG)$");

                if (!match.Success)
                {
                    LOG.WarnFormat("File exists in photo photo that does not appear to be a photo: '{0}'", fileName);
                    continue;
                }

                photos.Add(new PixPhoto
                {
                    FileName = fileName,
                    SeoName = StripPhotoExtension(AppHelper.SeoName(fileName)),
                    VirtualPath = StripRootPath(directoryPath),
                    DirectoryPath = directoryPath,
                });

                CheckForThumbnail(directoryPath, fileName);
            }
            return photos;
        }

        private static void CheckForThumbnail(string directory, string photoName)
        {
            //ImageResize.ResizeImage(directory, photoName);
            ImageLib.ResizeImage(directory, photoName);
        }

        private static void CheckCacheDirectory(string directory)
        {
            var cacheDir = Path.Combine(directory, AppHelper.CacheDirctory);

            if (Directory.Exists(cacheDir)) return;

            LOG.InfoFormat("Creating cache directory '{0}'.", directory);
            Directory.CreateDirectory(cacheDir);
        }

        private static string GetNameFromPath(string path)
        {
            return path.Substring(path.LastIndexOf('\\') + 1);
        }

        private static string StripRootPath(string path)
        {
            return path.Replace(_rootDirectory, "");
        }

        private static string StripPhotoExtension(string photoName)
        {
            return photoName.Substring(0, photoName.LastIndexOf("."));
        }
    }
}